﻿<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link href="css/main.css" rel="stylesheet" />
    <script type="text/javascript">
        var processor = function () {
            var _canvas;
            var _ctx;
            var _imgInstance={loaded:false};
            var _container;
           
            //Observer
            var event = function (sender) {
                this._sender = sender;
                this._listeners = [];
            }

            event.prototype.attach = function (handler) {
                if (typeof handler == "function") {
                    this._listeners.push(handler);
                }
            }

            event.prototype.notify = function () {
                for (var i = 0, ci; ci = this._listeners[i]; i++) {
                    ci.apply(this._sender, arguments);
                }
            }

            return {
                applyContainer: function (cid) {
                    _container = document.getElementById(cid);
                    _canvas = document.createElement("CANVAS");
                    _ctx = _canvas.getContext("2d");
                    var _canvasMousemoveHandler = new event(_canvas);
                    var _canvasMouseDownHandler = new event(_canvas);
                    var _frameStringGeneratedHandler = new event(this);
                    var _drawFinishhandler = new event(this);
                    var _scanInprogressHandler = new event(this);
                    var _resetHandler = new event(this);

                    var _allFrames = [];
                    var _allData = {};
                    var _counter = 0;
                    var _seeds = [];


                    var getMouseCord = function (sender, evt) {
                        return evt.pageX || evt.pageY ? { x: evt.pageX - sender.offsetLeft, y: evt.pageY - sender.offsetTop } : {
                            x: (evt.clientX + document.body.scrollLeft - document.body.clientLeft) - sender.offsetLeft,
                            y: (evt.clientY + document.body.scrollTop - document.body.clientTop) - sender.offsetTop
                        };

                    }

                    _canvas.onmousemove = function (e) {
                        var _evt = e || window.event;
                        var _mouseCord = getMouseCord(this, _evt);
                        _canvasMousemoveHandler.notify(_mouseCord);
                    }

                    _canvas.onmousedown = function (e) {
                        var _evt = e || window.event;
                        var _mouseCord = getMouseCord(this, _evt);
                        _seeds.push([_mouseCord.x, _mouseCord.y]);
                        _canvasMouseDownHandler.notify(_mouseCord, _seeds);
                    }

                    var reset = function () {
                        _imgInstance.loaded = false;
                        var _allFrames = [];
                        var _allData = {};
                        var _counter = 0;
                        var _seeds = [];
                        _resetHandler.notify();
                    }

                    return {
                        loadImg: function (url) {
                            reset();
                            var _img = new Image();
                            _img.src = url;

                            _img.onload = function () {
                                _imgInstance.obj = _img;
                                _imgInstance.width = _img.width;
                                _imgInstance.height = _img.height;
                                _imgInstance.loaded = true;
                            }
                        }//img loaded
                        , drawImg: function () {
                                    if (!_imgInstance.loaded) {
                                        setTimeout(arguments.callee, 50);
                                        return;
                                    }
                                    _canvas.width = _imgInstance.width;
                                    _canvas.height = _imgInstance.height;

                                    _ctx.clearRect(0, 0, _canvas.getAttribute("width"), _canvas.getAttribute("height"));
                                    _ctx.drawImage(_imgInstance.obj, 0, 0, _imgInstance.width, _imgInstance.height);
                                    _container.appendChild(_canvas);
                                }//canvas created
                        , attachMouseOverHandler: function (func) {
                                    _canvasMousemoveHandler.attach(func);
                                }
                        , attachMouseDownHandler: function (func) {
                                    _canvasMouseDownHandler.attach(func);
                                }
                        , attachDrawFinishingHandler: function (func) {
                                    _drawFinishhandler.attach(func);
                                }
                        , attachFrameStringHandler: function (func) {
                                    _frameStringGeneratedHandler.attach(func);
                                }
                        , attachSanInprogressHandler: function (func) {
                                    _scanInprogressHandler.attach(func);
                        }
                        , attachResetHandler: function (func) {
                            _resetHandler.attach(func);
                        }
                        , scan: function () {
                                    if (!_ctx) { throw "canvas not ready"; };
                                    var _imgData = _ctx.getImageData(0, 0, _canvas.width, _canvas.height);
                                    var _pixes = _imgData.data;
                                    var _x = _imgData.width;
                                    var _y = _imgData.height;

                                    var getPixColor = function (x, y) {
                                        var ind = (_x * y + x) * 4;
                                        return {
                                            R: _pixes[ind]
                                            , G: _pixes[ind + 1]
                                            , B: _pixes[ind + 2]
                                            , A: _pixes[ind + 3]
                                        }
                                    }

                                    var _stdPix = getPixColor(1, 1);

                                    var pixCompare = function (std, point) {
                                        for (var i in std) {
                                            if (std[i] != point[i]) {
                                                return false;
                                            }
                                        }
                                        return true;
                                    }

                                    var get8Pixes = function (x, y, X, Y) {
                                        return {
                                            n: { x: x, y: Math.max(0, y - 1) }
                                            , s: { x: x, y: Math.min(y + 1, Y) }
                                            , w: { x: Math.max(0, x - 1), y: y }
                                            , e: { x: Math.min(x + 1, X), y: y }
                                            , nw: { x: Math.max(0, x - 1), y: Math.max(0, y - 1) }
                                            , ne: { x: Math.min(x + 1, X), y: Math.max(0, y - 1) }
                                            , sw: { x: Math.max(0, x - 1), y: Math.min(y + 1, Y) }
                                            , se: { x: Math.min(x + 1, X), y: Math.min(y + 1, Y) }
                                        }

                                    }

                                    var Scan = function (x, y, posInfo) {
                                        var point = getPixColor(x, y);
                                        if (pixCompare(_stdPix, point)) { return; }
                                        var _index = x + "_" + y;
                                        if (_allData[_index]) { return; }
                                        var _posInfo;
                                        if (posInfo == undefined) {
                                            _posInfo = { MinX: x, MinY: y, MaxX: 0, MaxY: 0 };
                                            _allFrames.push(_posInfo);
                                        }
                                        else {
                                            _posInfo = posInfo;
                                        }

                                        _posInfo.MinX = Math.min(_posInfo.MinX, x);
                                        _posInfo.MinY = Math.min(_posInfo.MinY, y);
                                        _posInfo.MaxX = Math.max(_posInfo.MaxX, x);
                                        _posInfo.MaxY = Math.max(_posInfo.MaxY, y);
                                        _allData[_index] = point;
                                        _scanInprogressHandler.notify(++_counter, _allFrames, _seeds);
                                        var _around = get8Pixes(x, y, _x - 1, _y - 1);
                                        var _self = arguments.callee;
                                        for (var i in _around) {
                                            (function (point) {
                                                setTimeout(function () { _self.call(null, point.x, point.y, _posInfo) }, 50);
                                                //_self.call(null, point.x, point.y);
                                            })(_around[i]);

                                        }

                                    }

                                    for (var i = 0, ci; ci = _seeds[i]; i++) {
                                        Scan(ci[0], ci[1]);
                                    }
                                }//scan
                        , getStrInfo: function () {
                                    var stdH = _allFrames[0].MaxY - _allFrames[0].MinY;
                                    var _strBuild = [];
                                    _strBuild.push("[");
                                    for (var i = 0, ci; ci = _allFrames[i]; i++) {
                                        var h = ci.MaxY - ci.MinY;
                                        var yc = stdH - h;
                                        _strBuild.push(_strBuild.length == 1 ? "{" : ",{");
                                        _strBuild.push("x:" + ci.MinX);
                                        _strBuild.push(",y:" + ci.MinY);
                                        _strBuild.push(",w:" + (ci.MaxX - ci.MinX));
                                        _strBuild.push(",h:" + h);
                                        _strBuild.push(",yc:" + yc);
                                        _strBuild.push(",s:" + 0);
                                        _strBuild.push("}");
                                    }
                                    _strBuild.push("]");
                                    var _str = _strBuild.join("");
                                    _frameStringGeneratedHandler.notify(_str);
                                    return _str;
                                }//getStrInfo
                        , getArrayInfo: function () {
                                    //empty
                                    return [];
                                }
                        
                    }//container loaded
                }
            }
        }();

        var pointer;

        function doit() {
            var _url = document.getElementById("source").value;
            pointer.loadImg(_url);
            pointer.drawImg();
        }

        window.onload = function () {
            pointer = processor.applyContainer("container");
            pointer.attachMouseOverHandler(
                function (cord) {
                    document.getElementById("mouse").innerHTML = "X: " + cord.x + "  Y: " + cord.y;
                });
            pointer.attachMouseDownHandler(function (cord, seeds) {
                var _str = [];
                var counter = 0;
                _str.push("There are "+seeds.length+" points currently been added, they are:");
                for(var i=0,ci;ci=seeds[i];i++)
                {
                    if (counter++ % 4 == 0) { _str.push("<br />"); counter = 1; }
                    else {
                        _str.push("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
                    }
                    _str.push("X:" + ci[0] + ", Y:" + ci[1]);
                }
                document.getElementById("selected").innerHTML = _str.join("");

            });

            pointer.attachFrameStringHandler(function (str) {
                document.getElementById("result").value = str;
            });

            pointer.attachSanInprogressHandler(function (num, frames, tags) {
                document.getElementById("counter").innerHTML=num+" pixes are scanned so far.";

            });

            pointer.attachResetHandler(function () {
                document.getElementById("counter").innerHTML = "";
                document.getElementById("result").value = "";
                document.getElementById("mouse").innerHTML = "";
                document.getElementById("selected").innerHTML = "";
            });
        }

    </script>
</head>
<body>
    <div id="header">
        <div id="left">
            <div class="source"><input type="text" id="source" value="girl.jpg"/></div>
            <div id="mouse"></div>
            <div id="counter"></div>
            
            <div id="buttonlayer">
                <button class="button small green" id="render" onclick="doit();">Render</button>
                <button class="button small blue left15" id="scan" onclick="pointer.scan()">Scan</button>
                <button class="button small orange left15" id="analysis" onclick="pointer.getStrInfo()">Analysis</button>
            </div>
        </div>

        <div id="center">
            <div id="selected"></div>
        </div>
        <div id="right">
            <textarea id="result">
            </textarea>
        </div>
    </div>
    <div class="shadow"></div>
    
    
    <div id="container"></div>
</body>
</html>
